home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / GIFLIB12.ARJ / GIFFIX.C < prev    next >
C/C++ Source or Header  |  1991-05-12  |  7KB  |  216 lines

  1. /*****************************************************************************
  2. *   "Gif-Lib" - Yet another gif library.                     *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, Jul. 1989   *
  5. ******************************************************************************
  6. * Program to attempt and fix broken GIF images. Currently fix the following: *
  7. * 1. EOF terminates before end of image size (adds black in the end).        *
  8. * Options:                                     *
  9. * -q : quite printing mode.                             *
  10. * -h : on line help                                 *
  11. ******************************************************************************
  12. * History:                                     *
  13. * 5 May 91 - Version 1.0 by Gershon Elber.                     *
  14. *****************************************************************************/
  15.  
  16. #ifdef __MSDOS__
  17. #include <stdlib.h>
  18. #include <alloc.h>
  19. #endif /* __MSDOS__ */
  20.  
  21. #include <stdio.h>
  22. #include <ctype.h>
  23. #include <string.h>
  24. #include "gif_lib.h"
  25. #include "getarg.h"
  26.  
  27. #define PROGRAM_NAME    "GifFix"
  28.  
  29. #ifdef __MSDOS__
  30. extern unsigned int
  31.     _stklen = 16384;                 /* Increase default stack size. */
  32. #endif /* __MSDOS__ */
  33.  
  34. #ifdef SYSV
  35. static char *VersionStr =
  36.         "Gif library module,\t\tGershon Elber\n\
  37.     (C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
  38. static char
  39.     *CtrlStr = "GifFix q%- h%- GifFile!*s";
  40. #else
  41. static char
  42.     *VersionStr =
  43.     PROGRAM_NAME
  44.     GIF_LIB_VERSION
  45.     "    Gershon Elber,    "
  46.     __DATE__ ",   " __TIME__ "\n"
  47.     "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
  48. static char
  49.     *CtrlStr =
  50.     PROGRAM_NAME
  51.     " q%- h%- GifFile!*s";
  52. #endif /* SYSV */
  53.  
  54. /* Make some variables global, so we could access them faster: */
  55. static int
  56.     ImageNum = 0;
  57.  
  58. static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut);
  59.  
  60. /******************************************************************************
  61. * Interpret the command line and scan the given GIF file.              *
  62. ******************************************************************************/
  63. void main(int argc, char **argv)
  64. {
  65.     int    i, j, Error, NumFiles, ExtCode, ColorMapSize, Row, Col, Width, Height,
  66.     DarkestColor = 0, ColorIntens = 10000, HelpFlag = FALSE;
  67.     GifRecordType RecordType;
  68.     GifByteType *Extension;
  69.     char **FileName = NULL;
  70.     GifRowType LineBuffer;
  71.     GifColorType *ColorMap;
  72.     GifFileType *GifFileIn = NULL, *GifFileOut = NULL;
  73.  
  74.     if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, &HelpFlag,
  75.         &NumFiles, &FileName)) != FALSE ||
  76.         (NumFiles > 1 && !HelpFlag)) {
  77.     if (Error)
  78.         GAPrintErrMsg(Error);
  79.     else if (NumFiles > 1)
  80.         GIF_MESSAGE("Error in command line parsing - one GIF file please.");
  81.     GAPrintHowTo(CtrlStr);
  82.     exit(1);
  83.     }
  84.  
  85.     if (HelpFlag) {
  86.     fprintf(stderr, VersionStr);
  87.     GAPrintHowTo(CtrlStr);
  88.     exit(0);
  89.     }
  90.  
  91.     if (NumFiles == 1) {
  92.     if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL)
  93.         QuitGifError(GifFileIn, GifFileOut);
  94.     }
  95.     else {
  96.     /* Use the stdin instead: */
  97.     if ((GifFileIn = DGifOpenFileHandle(0)) == NULL)
  98.         QuitGifError(GifFileIn, GifFileOut);
  99.     }
  100.  
  101.     /* Open stdout for the output file: */
  102.     if ((GifFileOut = EGifOpenFileHandle(1)) == NULL)
  103.     QuitGifError(GifFileIn, GifFileOut);
  104.  
  105.     /* Dump out exactly same screen information: */
  106.     if (EGifPutScreenDesc(GifFileOut,
  107.     GifFileIn -> SWidth, GifFileIn -> SHeight,
  108.     GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor,
  109.     GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR)
  110.     QuitGifError(GifFileIn, GifFileOut);
  111.  
  112.     if ((LineBuffer = (GifRowType) malloc(GifFileIn -> SWidth)) == NULL)
  113.     GIF_EXIT("Failed to allocate memory required, aborted.");
  114.  
  115.     /* Scan the content of the GIF file and load the image(s) in: */
  116.     do {
  117.     if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
  118.         QuitGifError(GifFileIn, GifFileOut);
  119.  
  120.     switch (RecordType) {
  121.         case IMAGE_DESC_RECORD_TYPE:
  122.         if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
  123.             QuitGifError(GifFileIn, GifFileOut);
  124.         if (GifFileIn -> IInterlace)
  125.             GIF_EXIT("Cannt fix interlaced images.");
  126.  
  127.         Row = GifFileIn -> ITop; /* Image Position relative to Screen. */
  128.         Col = GifFileIn -> ILeft;
  129.         Width = GifFileIn -> IWidth;
  130.         Height = GifFileIn -> IHeight;
  131.         GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
  132.             PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
  133.  
  134.         /* Put the image descriptor to out file: */
  135.         if (EGifPutImageDesc(GifFileOut, Col, Row, Width, Height,
  136.             FALSE, GifFileIn -> IBitsPerPixel,
  137.             GifFileIn -> IColorMap) == GIF_ERROR)
  138.             QuitGifError(GifFileIn, GifFileOut);
  139.  
  140.         /* Find the darkest color in color map to use as a filler. */
  141.         ColorMap = (GifFileIn -> IColorMap ? GifFileIn -> IColorMap :
  142.                              GifFileIn -> SColorMap);
  143.         ColorMapSize = 1 << (GifFileIn -> IColorMap ?
  144.                         GifFileIn -> IBitsPerPixel :
  145.                         GifFileIn -> SBitsPerPixel);
  146.         for (i = 0; i < ColorMapSize; i++) {
  147.             j = ((int) ColorMap[i].Red) * 30 +
  148.             ((int) ColorMap[i].Green) * 59 +
  149.             ((int) ColorMap[i].Blue) * 11;
  150.             if (j < ColorIntens) {
  151.             ColorIntens = j;
  152.             DarkestColor = i;
  153.             }
  154.         }
  155.  
  156.         /* Load the image, and dump it. */
  157.         for (i = 0; i < Height; i++) {
  158.             GifQprintf("\b\b\b\b%-4d", i);
  159.             if (DGifGetLine(GifFileIn, LineBuffer, Width)
  160.             == GIF_ERROR) break;
  161.             if (EGifPutLine(GifFileOut, LineBuffer, Width)
  162.             == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut);
  163.         }
  164.  
  165.         if (i < Height) {
  166.             fprintf(stderr, "\nFollowing error occured (and ignored):");
  167.             PrintGifError();
  168.  
  169.             /* Fill in with the darkest color in color map. */
  170.             for (j = 0; j < Width; j++)
  171.             LineBuffer[j] = DarkestColor;
  172.             for (; i < Height; i++)
  173.             if (EGifPutLine(GifFileOut, LineBuffer, Width)
  174.                 == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut);
  175.         }
  176.         break;
  177.         case EXTENSION_RECORD_TYPE:
  178.         /* Skip any extension blocks in file: */
  179.         if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR)
  180.             QuitGifError(GifFileIn, GifFileOut);
  181.         if (EGifPutExtension(GifFileOut, ExtCode, Extension[0],
  182.                             Extension) == GIF_ERROR)
  183.             QuitGifError(GifFileIn, GifFileOut);
  184.  
  185.         /* No support to more than one extension blocks, so discard: */
  186.         while (Extension != NULL) {
  187.             if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_ERROR)
  188.             QuitGifError(GifFileIn, GifFileOut);
  189.         }
  190.         break;
  191.         case TERMINATE_RECORD_TYPE:
  192.         break;
  193.         default:            /* Should be traps by DGifGetRecordType. */
  194.         break;
  195.     }
  196.     }
  197.     while (RecordType != TERMINATE_RECORD_TYPE);
  198.  
  199.     if (DGifCloseFile(GifFileIn) == GIF_ERROR)
  200.     QuitGifError(GifFileIn, GifFileOut);
  201.     if (EGifCloseFile(GifFileOut) == GIF_ERROR)
  202.     QuitGifError(GifFileIn, GifFileOut);
  203. }
  204.  
  205. /******************************************************************************
  206. * Close both input and output file (if open), and exit.                  *
  207. ******************************************************************************/
  208. static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut)
  209. {
  210.     fprintf(stderr, "\nFollowing unrecoverable error occured:");
  211.     PrintGifError();
  212.     if (GifFileIn != NULL) DGifCloseFile(GifFileIn);
  213.     if (GifFileOut != NULL) EGifCloseFile(GifFileOut);
  214.     exit(1);
  215. }
  216.